#include"arm.h"


#ifndef __GNUC__
#pragma warning(disable : 4700)
#endif

#define MASK_ZF 0x40
#define MASK_AF 0x10
#define MASK_PF 0x4
#define MASK_OF 0x800
#define MASK_CF 0x1 
#define MASK_SF 0x80

__u32 arm_sub(__u32 op1,__u32 op2,__u32 *p_flag)
{

	__u32 result;
	__u32 flag=*p_flag;
	__u8  x86_flag;

	__asm mov ebx,op1;
	__asm sub ebx,op2;
	__asm lahf;
	__asm mov x86_flag,ah;
	__asm mov result,ebx;

//N Flag = Rd[31]
//Z Flag = if Rd == 0 then 1 else 0
//C 
//V Flag = OverflowFrom(Rn + immed_3)
	if((x86_flag&MASK_CF)==0)
	{
		SET_BIT(flag,CPSR_BIT_C);
	}
	else
	{
		CLR_BIT(flag,CPSR_BIT_C);
	}

	if(x86_flag&MASK_OF)
	{
		SET_BIT(flag,CPSR_BIT_V);
	}
	else
	{
		CLR_BIT(flag,CPSR_BIT_V);
	}

	*p_flag=flag;
	return result;
	
}

__u32 arm_add(__u32 op1,__u32 op2,__u32 *p_flag)
{
	__u32 result;
	__u32 flag=*p_flag;
	__u8  x86_flag;

	__asm mov ebx,op1;
	__asm add ebx,op2;
	__asm lahf;
	__asm mov x86_flag,ah;
	__asm mov result,ebx;

//N Flag = Rd[31]
//Z Flag = if Rd == 0 then 1 else 0
//C Flag = CarryFrom(Rn + immed_3)
//V Flag = OverflowFrom(Rn + immed_3)
	if(x86_flag&MASK_CF)
	{
		SET_BIT(flag,CPSR_BIT_C);
	}
	else
	{
		CLR_BIT(flag,CPSR_BIT_C);
	}

	if(x86_flag&MASK_OF)
	{
		SET_BIT(flag,CPSR_BIT_V);
	}
	else
	{
		CLR_BIT(flag,CPSR_BIT_V);
	}
	*p_flag=flag;

	return result;
}
__u32 arm_adc(__u32 op1,__u32 op2,__u32 *p_flag)
{
	__u32 result;
	__u32 flag=*p_flag;
	if(*p_flag!=0)
		op2++;
	result=op1+op2;

//N Flag = Rd[31]
//Z Flag = if Rd == 0 then 1 else 0
//C Flag = CarryFrom(Rn + immed_3)
//V Flag = OverflowFrom(Rn + immed_3)

	return arm_add(op1,op2,p_flag);
}
__u32 arm_sbc(__u32 op1,__u32 op2,__u32 *p_flag)
{
	__u32 result;
	__u32 flag=*p_flag;
	if(*p_flag==0)
		op2++;

	return arm_sub(op1,op2,p_flag);
}



